home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / me39src1.arc / EVAL.C < prev    next >
C/C++ Source or Header  |  1987-07-13  |  19KB  |  788 lines

  1. /*    EVAL.C:    Expresion evaluation functions for
  2.         MicroEMACS
  3.  
  4.     written 1986 by Daniel Lawrence                */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "edef.h"
  9. #include    "evar.h"
  10.  
  11. varinit()        /* initialize the user variable list */
  12.  
  13. {
  14.     register int i;
  15.  
  16.     for (i=0; i < MAXVARS; i++)
  17.         uv[i].u_name[0] = 0;
  18. }
  19.  
  20. char *gtfun(fname)    /* evaluate a function */
  21.  
  22. char *fname;        /* name of function to evaluate */
  23.  
  24. {
  25.     register int fnum;        /* index to function to eval */
  26.     register int status;        /* return status */
  27.     char arg1[NSTRING];        /* value of first argument */
  28.     char arg2[NSTRING];        /* value of second argument */
  29.     char arg3[NSTRING];        /* value of third argument */
  30.     static char result[2 * NSTRING];    /* string result */
  31. #if    ENVFUNC
  32.     char *getenv();
  33. #endif
  34.  
  35.     /* look the function up in the function table */
  36.     fname[3] = 0;    /* only first 3 chars significant */
  37.     mklower(fname);    /* and let it be upper or lower case */
  38.     for (fnum = 0; fnum < NFUNCS; fnum++)
  39.         if (strcmp(fname, funcs[fnum].f_name) == 0)
  40.             break;
  41.  
  42.     /* return errorm on a bad reference */
  43.     if (fnum == NFUNCS)
  44.         return(errorm);
  45.  
  46.     /* if needed, retrieve the first argument */
  47.     if (funcs[fnum].f_type >= MONAMIC) {
  48.         if ((status = macarg(arg1)) != TRUE)
  49.             return(errorm);
  50.  
  51.         /* if needed, retrieve the second argument */
  52.         if (funcs[fnum].f_type >= DYNAMIC) {
  53.             if ((status = macarg(arg2)) != TRUE)
  54.                 return(errorm);
  55.     
  56.             /* if needed, retrieve the third argument */
  57.             if (funcs[fnum].f_type >= TRINAMIC)
  58.                 if ((status = macarg(arg3)) != TRUE)
  59.                     return(errorm);
  60.         }
  61.     }
  62.         
  63.  
  64.     /* and now evaluate it! */
  65.     switch (fnum) {
  66.         case UFADD:    return(itoa(atoi(arg1) + atoi(arg2)));
  67.         case UFSUB:    return(itoa(atoi(arg1) - atoi(arg2)));
  68.         case UFTIMES:    return(itoa(atoi(arg1) * atoi(arg2)));
  69.         case UFDIV:    return(itoa(atoi(arg1) / atoi(arg2)));
  70.         case UFMOD:    return(itoa(atoi(arg1) % atoi(arg2)));
  71.         case UFNEG:    return(itoa(-atoi(arg1)));
  72.         case UFCAT:    strcpy(result, arg1);
  73.                 return(strcat(result, arg2));
  74.         case UFLEFT:    return(strncpy(result, arg1, atoi(arg2)));
  75.         case UFRIGHT:    return(strcpy(result, &arg1[atoi(arg2)-1]));
  76.         case UFMID:    return(strncpy(result, &arg1[atoi(arg2)-1],
  77.                     atoi(arg3)));
  78.         case UFNOT:    return(ltos(stol(arg1) == FALSE));
  79.         case UFEQUAL:    return(ltos(atoi(arg1) == atoi(arg2)));
  80.         case UFLESS:    return(ltos(atoi(arg1) < atoi(arg2)));
  81.         case UFGREATER:    return(ltos(atoi(arg1) > atoi(arg2)));
  82.         case UFSEQUAL:    return(ltos(strcmp(arg1, arg2) == 0));
  83.         case UFSLESS:    return(ltos(strcmp(arg1, arg2) < 0));
  84.         case UFSGREAT:    return(ltos(strcmp(arg1, arg2) > 0));
  85.         case UFIND:    return(getval(arg1));
  86.         case UFAND:    return(ltos(stol(arg1) && stol(arg2)));
  87.         case UFOR:    return(ltos(stol(arg1) || stol(arg2)));
  88.         case UFLENGTH:    return(itoa(strlen(arg1)));
  89.         case UFUPPER:    return(mkupper(arg1));
  90.         case UFLOWER:    return(mklower(arg1));
  91.         case UFTRUTH:    return(ltos(atoi(arg1) == 42));
  92.         case UFASCII:    return(itoa((int)arg1[0]));
  93.         case UFCHR:    result[0] = atoi(arg1);
  94.                 result[1] = 0;
  95.                 return(result);
  96.         case UFGTKEY:    result[0] = tgetc();
  97.                 result[1] = 0;
  98.                 return(result);
  99.         case UFRND:    return(itoa((ernd() % abs(atoi(arg1))) + 1));
  100.         case UFABS:    return(itoa(abs(atoi(arg1))));
  101.         case UFSINDEX:    return(itoa(sindex(arg1, arg2)));
  102.         case UFENV:
  103. #if    ENVFUNC
  104.                 return(getenv(arg1) == NULL ? "" : getenv(arg1));
  105. #else
  106.                 return("");
  107. #endif
  108.         case UFBIND:    return(transbind(arg1));
  109.     }
  110.  
  111.     exit(-11);    /* never should get here */
  112. }
  113.  
  114. char *gtusr(vname)    /* look up a user var's value */
  115.  
  116. char *vname;        /* name of user variable to fetch */
  117.  
  118. {
  119.  
  120.     register int vnum;    /* ordinal number of user var */
  121.  
  122.     /* scan the list looking for the user var name */
  123.     for (vnum = 0; vnum < MAXVARS; vnum++)
  124.         if (strcmp(vname, uv[vnum].u_name) == 0)
  125.             break;
  126.  
  127.     /* return errorm on a bad reference */
  128.     if (vnum == MAXVARS)
  129.         return(errorm);
  130.  
  131.     return(uv[vnum].u_value);
  132. }
  133.  
  134. char *gtenv(vname)
  135.  
  136. char *vname;        /* name of environment variable to retrieve */
  137.  
  138. {
  139.     register int vnum;    /* ordinal number of var refrenced */
  140.     char *getkill();
  141.  
  142.     /* scan the list, looking for the referenced name */
  143.     for (vnum = 0; vnum < NEVARS; vnum++)
  144.         if (strcmp(vname, envars[vnum]) == 0)
  145.             break;
  146.  
  147.     /* return errorm on a bad reference */
  148.     if (vnum == NEVARS)
  149.         return(errorm);
  150.  
  151.     /* otherwise, fetch the appropriate value */
  152.     switch (vnum) {
  153.         case EVFILLCOL:    return(itoa(fillcol));
  154.         case EVPAGELEN:    return(itoa(term.t_nrow + 1));
  155.         case EVCURCOL:    return(itoa(getccol(FALSE)));
  156.         case EVCURLINE: return(itoa(getcline()));
  157.         case EVRAM:    return(itoa((int)(envram / 1024l)));
  158.         case EVFLICKER:    return(ltos(flickcode));
  159.         case EVCURWIDTH:return(itoa(term.t_nrow));
  160.         case EVCBUFNAME:return(curbp->b_bname);
  161.         case EVCFNAME:    return(curbp->b_fname);
  162.         case EVSRES:    return(sres);
  163.         case EVDEBUG:    return(ltos(macbug));
  164.         case EVSTATUS:    return(ltos(cmdstatus));
  165.         case EVPALETTE:    return(palstr);
  166.         case EVASAVE:    return(itoa(gasave));
  167.         case EVACOUNT:    return(itoa(gacount));
  168.         case EVLASTKEY: return(itoa(lastkey));
  169.         case EVCURCHAR:
  170.             return(curwp->w_dotp->l_used ==
  171.                     curwp->w_doto ? itoa('\n') :
  172.                 itoa(lgetc(curwp->w_dotp, curwp->w_doto)));
  173.         case EVDISCMD:    return(ltos(discmd));
  174.         case EVVERSION:    return(VERSION);
  175.         case EVPROGNAME:return(PROGNAME);
  176.         case EVSEED:    return(itoa(seed));
  177.         case EVDISINP:    return(ltos(disinp));
  178.         case EVWLINE:    return(itoa(curwp->w_ntrows));
  179.         case EVCWLINE:    return(itoa(getwpos()));
  180.         case EVTARGET:    saveflag = lastflag;
  181.                 return(itoa(curgoal));
  182.         case EVSEARCH:    return(pat);
  183.         case EVREPLACE:    return(rpat);
  184.         case EVMATCH:    return((patmatch == NULL)? "": patmatch);
  185.         case EVKILL:    return(getkill());
  186.         case EVCMODE:    return(itoa(curbp->b_mode));
  187.         case EVGMODE:    return(itoa(gmode));
  188.         case EVTPAUSE:    return(itoa(term.t_pause));
  189.         case EVPENDING:
  190. #if    TYPEAH
  191.                 return(ltos(typahead()));
  192. #else
  193.                 return(falsem);
  194. #endif
  195.         case EVLWIDTH:    return(itoa(llength(curwp->w_dotp)));
  196.         case EVLINE:    return(getctext());
  197.     }
  198.     exit(-12);    /* again, we should never get here */
  199. }
  200.  
  201. char *getkill()        /* return some of the contents of the kill buffer */
  202.  
  203. {
  204.     register int size;    /* max number of chars to return */
  205.     char value[NSTRING];    /* temp buffer for value */
  206.  
  207.     if (kbufh == NULL)
  208.         /* no kill buffer....just a null string */
  209.         value[0] = 0;
  210.     else {
  211.         /* copy in the contents... */
  212.         if (kused < NSTRING)
  213.             size = kused;
  214.         else
  215.             size = NSTRING - 1;
  216.         strncpy(value, kbufh->d_chunk, size);
  217.     }
  218.  
  219.     /* and return the constructed value */
  220.     return(value);
  221. }
  222.  
  223. int setvar(f, n)        /* set a variable */
  224.  
  225. int f;        /* default flag */
  226. int n;        /* numeric arg (can overide prompted value) */
  227.  
  228. {
  229.     register int status;    /* status return */
  230. #if    DEBUGM
  231.     register char *sp;    /* temp string pointer */
  232.     register char *ep;    /* ptr to end of outline */
  233. #endif
  234.     VDESC vd;        /* variable num/type */
  235.     char var[NVSIZE+1];    /* name of variable to fetch */
  236.     char value[NSTRING];    /* value to set variable to */
  237.  
  238.     /* first get the variable to set.. */
  239.     if (clexec == FALSE) {
  240.         status = mlreply("Variable to set: ", &var[0], NVSIZE);
  241.         if (status != TRUE)
  242.             return(status);
  243.     } else {    /* macro line argument */
  244.         /* grab token and skip it */
  245.         execstr = token(execstr, var);
  246.     }
  247.  
  248.     /* check the legality and find the var */
  249.     findvar(var, &vd);
  250.     
  251.     /* if its not legal....bitch */
  252.     if (vd.v_type == -1) {
  253.         mlwrite("%%No such variable as '%s'", var);
  254.         return(FALSE);
  255.     }
  256.  
  257.     /* get the value for that variable */
  258.     if (f == TRUE)
  259.         strcpy(value, itoa(n));
  260.     else {
  261.         status = mlreply("Value: ", &value[0], NSTRING);
  262.         if (status != TRUE)
  263.             return(status);
  264.     }
  265.  
  266.     /* and set the appropriate value */
  267.     status = svar(&vd, value);
  268.  
  269. #if    DEBUGM
  270.     /* if $debug == TRUE, every assignment will echo a statment to
  271.        that effect here. */
  272.     
  273.     if (macbug) {
  274.         strcpy(outline, "(((");
  275.  
  276.         /* assignment status */
  277.         strcat(outline, ltos(status));
  278.         strcat(outline, ":");
  279.  
  280.         /* variable name */
  281.         strcat(outline, var);
  282.         strcat(outline, ":");
  283.  
  284.         /* and lastly the value we tried to assign */
  285.         strcat(outline, value);
  286.         strcat(outline, ")))");
  287.  
  288.         /* expand '%' to "%%" so mlwrite wont bitch */
  289.         sp = outline;
  290.         while (*sp)
  291.             if (*sp++ == '%') {
  292.                 /* advance to the end */
  293.                 ep = --sp;
  294.                 while (*ep++)
  295.                     ;
  296.                 /* null terminate the string one out */
  297.                 *(ep + 1) = 0;
  298.                 /* copy backwards */
  299.                 while(ep-- > sp)
  300.                     *(ep + 1) = *ep;
  301.  
  302.                 /* and advance sp past the new % */
  303.                 sp += 2;                    
  304.             }
  305.  
  306.         /* write out the debug line */
  307.         mlforce(outline);
  308.         update(TRUE);
  309.  
  310.         /* and get the keystroke to hold the output */
  311.         if (get1key() == abortc) {
  312.             mlforce("[Macro aborted]");
  313.             status = FALSE;
  314.         }
  315.     }
  316. #endif
  317.  
  318.     /* and return it */
  319.     return(status);
  320. }
  321.  
  322. findvar(var, vd)    /* find a variables type and name */
  323.  
  324. char *var;    /* name of var to get */
  325. VDESC *vd;    /* structure to hold type and ptr */
  326.  
  327. {
  328.     register int vnum;    /* subscript in varable arrays */
  329.     register int vtype;    /* type to return */
  330.  
  331. fvar:    vtype = -1;
  332.     switch (var[0]) {
  333.  
  334.         case '$': /* check for legal enviromnent var */
  335.             for (vnum = 0; vnum < NEVARS; vnum++)
  336.                 if (strcmp(&var[1], envars[vnum]) == 0) {
  337.                     vtype = TKENV;
  338.                     break;
  339.                 }
  340.             break;
  341.  
  342.         case '%': /* check for existing legal user variable */
  343.             for (vnum = 0; vnum < MAXVARS; vnum++)
  344.                 if (strcmp(&var[1], uv[vnum].u_name) == 0) {
  345.                     vtype = TKVAR;
  346.                     break;
  347.                 }
  348.             if (vnum < MAXVARS)
  349.                 break;
  350.  
  351.             /* create a new one??? */
  352.             for (vnum = 0; vnum < MAXVARS; vnum++)
  353.                 if (uv[vnum].u_name[0] == 0) {
  354.                     vtype = TKVAR;
  355.                     strcpy(uv[vnum].u_name, &var[1]);
  356.                     break;
  357.                 }
  358.             break;
  359.  
  360.         case '&':    /* indirect operator? */
  361.             var[4] = 0;
  362.             if (strcmp(&var[1], "ind") == 0) {
  363.                 /* grab token, and eval it */
  364.                 execstr = token(execstr, var);
  365.                 strcpy(var, getval(var));
  366.                 goto fvar;
  367.             }
  368.     }
  369.  
  370.     /* return the results */
  371.     vd->v_num = vnum;
  372.     vd->v_type = vtype;
  373.     return;
  374. }
  375.  
  376. int svar(var, value)        /* set a variable */
  377.  
  378. VDESC *var;    /* variable to set */
  379. char *value;    /* value to set to */
  380.  
  381. {
  382.     register int vnum;    /* ordinal number of var refrenced */
  383.     register int vtype;    /* type of variable to set */
  384.     register int status;    /* status return */
  385.     register int c;        /* translated character */
  386.     register char * sp;    /* scratch string pointer */
  387.  
  388.     /* simplify the vd structure (we are gonna look at it a lot) */
  389.     vnum = var->v_num;
  390.     vtype = var->v_type;
  391.  
  392.     /* and set the appropriate value */
  393.     status = TRUE;
  394.     switch (vtype) {
  395.     case TKVAR: /* set a user variable */
  396.         if (uv[vnum].u_value != NULL)
  397.             free(uv[vnum].u_value);
  398.         sp = malloc(strlen(value) + 1);
  399.         if (sp == NULL)
  400.             return(FALSE);
  401.         strcpy(sp, value);
  402.         uv[vnum].u_value = sp;
  403.         break;
  404.  
  405.     case TKENV: /* set an environment variable */
  406.         status = TRUE;    /* by default */
  407.         switch (vnum) {
  408.         case EVFILLCOL:    fillcol = atoi(value);
  409.                 break;
  410.         case EVPAGELEN:    status = newsize(TRUE, atoi(value));
  411.                 break;
  412.         case EVCURCOL:    status = setccol(atoi(value));
  413.                 break;
  414.         case EVCURLINE:    status = gotoline(TRUE, atoi(value));
  415.                 break;
  416.         case EVRAM:    break;
  417.         case EVFLICKER:    flickcode = stol(value);
  418.                 break;
  419.         case EVCURWIDTH:status = newwidth(TRUE, atoi(value));
  420.                 break;
  421.         case EVCBUFNAME:strcpy(curbp->b_bname, value);
  422.                 curwp->w_flag |= WFMODE;
  423.                 break;
  424.         case EVCFNAME:    strcpy(curbp->b_fname, value);
  425.                 curwp->w_flag |= WFMODE;
  426.                 break;
  427.         case EVSRES:    status = TTrez(value);
  428.                 break;
  429.         case EVDEBUG:    macbug = stol(value);
  430.                 break;
  431.         case EVSTATUS:    cmdstatus = stol(value);
  432.                 break;
  433.         case EVPALETTE:    strncpy(palstr, value, 48);
  434.                 spal(palstr);
  435.                 break;
  436.         case EVASAVE:    gasave = atoi(value);
  437.                 break;
  438.         case EVACOUNT:    gacount = atoi(value);
  439.                 break;
  440.         case EVLASTKEY:    lastkey = atoi(value);
  441.                 break;
  442.         case EVCURCHAR:    ldelete(1, FALSE);    /* delete 1 char */
  443.                 c = atoi(value);
  444.                 if (c == '\n')
  445.                     lnewline(FALSE, 1);
  446.                 else
  447.                     linsert(1, c);
  448.                 backchar(FALSE, 1);
  449.                 break;
  450.         case EVDISCMD:    discmd = stol(value);
  451.                 break;
  452.         case EVVERSION:    break;
  453.         case EVPROGNAME:break;
  454.         case EVSEED:    seed = atoi(value);
  455.                 break;
  456.         case EVDISINP:    disinp = stol(value);
  457.                 break;
  458.         case EVWLINE:    status = resize(TRUE, atoi(value));
  459.                 break;
  460.         case EVCWLINE:    status = forwline(TRUE,
  461.                         atoi(value) - getwpos());
  462.                 break;
  463.         case EVTARGET:    curgoal = atoi(value);
  464.                 thisflag = saveflag;
  465.                 break;
  466.         case EVSEARCH:    strcpy(pat, value);
  467.                 rvstrcpy(tap, pat);
  468.                 mcclear();
  469.                 break;
  470.         case EVREPLACE:    strcpy(rpat, value);
  471.                 break;
  472.         case EVMATCH:    break;
  473.         case EVKILL:    break;
  474.         case EVCMODE:    curbp->b_mode = atoi(value);
  475.                 curwp->w_flag |= WFMODE;
  476.                 break;
  477.         case EVGMODE:    gmode = atoi(value);
  478.                 break;
  479.         case EVTPAUSE:    term.t_pause = atoi(value);
  480.                 break;
  481.         case EVPENDING:    break;
  482.         case EVLWIDTH:    break;
  483.         case EVLINE:    putctext(value);
  484.         }
  485.         break;
  486.     }
  487.     return(status);
  488. }
  489.  
  490. /*    atoi:    ascii string to integer......This is too
  491.         inconsistant to use the system's    */
  492.  
  493. atoi(st)
  494.  
  495. char *st;
  496.  
  497. {
  498.     int result;    /* resulting number */
  499.     int sign;    /* sign of resulting number */
  500.     char c;        /* current char being examined */
  501.  
  502.     result = 0;
  503.     sign = 1;
  504.  
  505.     /* skip preceding whitespace */
  506.     while (*st == ' ' || *st == '\t')
  507.         ++st;
  508.  
  509.     /* check for sign */
  510.     if (*st == '-') {
  511.         sign = -1;
  512.         ++st;
  513.     }
  514.     if (*st == '+')
  515.         ++st;
  516.  
  517.     /* scan digits, build value */
  518.     while ((c = *st++))
  519.         if (c >= '0' && c <= '9')
  520.             result = result * 10 + c - '0';
  521.         else
  522.             return(0);
  523.  
  524.     return(result * sign);
  525. }
  526.  
  527. /*    itoa:    integer to ascii string.......... This is too
  528.         inconsistant to use the system's    */
  529.  
  530. char *itoa(i)
  531.  
  532. int i;    /* integer to translate to a string */
  533.  
  534. {
  535.     register int digit;        /* current digit being used */
  536.     register char *sp;        /* pointer into result */
  537.     register int sign;        /* sign of resulting number */
  538.     static char result[INTWIDTH+1];    /* resulting string */
  539.  
  540.     /* record the sign...*/
  541.     sign = 1;
  542.     if (i < 0) {
  543.         sign = -1;
  544.         i = -i;
  545.     }
  546.  
  547.     /* and build the string (backwards!) */
  548.     sp = result + INTWIDTH;
  549.     *sp = 0;
  550.     do {
  551.         digit = i % 10;
  552.         *(--sp) = '0' + digit;    /* and install the new digit */
  553.         i = i / 10;
  554.     } while (i);
  555.  
  556.     /* and fix the sign */
  557.     if (sign == -1) {
  558.         *(--sp) = '-';    /* and install the minus sign */
  559.     }
  560.  
  561.     return(sp);
  562. }
  563.  
  564. int gettyp(token)    /* find the type of a passed token */
  565.  
  566. char *token;    /* token to analyze */
  567.  
  568. {
  569.     register char c;    /* first char in token */
  570.  
  571.     /* grab the first char (this is all we need) */
  572.     c = *token;
  573.  
  574.     /* no blanks!!! */
  575.     if (c == 0)
  576.         return(TKNUL);
  577.  
  578.     /* a numeric literal? */
  579.     if (c >= '0' && c <= '9')
  580.         return(TKLIT);
  581.  
  582.     switch (c) {
  583.         case '"':    return(TKSTR);
  584.  
  585.         case '!':    return(TKDIR);
  586.         case '@':    return(TKARG);
  587.         case '#':    return(TKBUF);
  588.         case '$':    return(TKENV);
  589.         case '%':    return(TKVAR);
  590.         case '&':    return(TKFUN);
  591.         case '*':    return(TKLBL);
  592.  
  593.         default:    return(TKCMD);
  594.     }
  595. }
  596.  
  597. char *getval(token)    /* find the value of a token */
  598.  
  599. char *token;        /* token to evaluate */
  600.  
  601. {
  602.     register int status;    /* error return */
  603.     register BUFFER *bp;    /* temp buffer pointer */
  604.     register int blen;    /* length of buffer argument */
  605.     register int distmp;    /* temporary discmd flag */
  606.     char pad[20];        /* pad 20 bytes on stack for safety */
  607.     char buf[NSTRING];    /* string buffer for some returns */
  608.  
  609.     switch (gettyp(token)) {
  610.         case TKNUL:    return("");
  611.  
  612.         case TKARG:    /* interactive argument */
  613.                 strcpy(token, getval(&token[1]));
  614.                 distmp = discmd;    /* echo it always! */
  615.                 discmd = TRUE;
  616.                 status = getstring(token,
  617.                        buf, NSTRING, ctoec('\n'));
  618.                 discmd = distmp;
  619.                 if (status == ABORT)
  620.                     return(errorm);
  621.                 return(buf);
  622.  
  623.         case TKBUF:    /* buffer contents fetch */
  624.  
  625.                 /* grab the right buffer */
  626.                 strcpy(token, getval(&token[1]));
  627.                 bp = bfind(token, FALSE, 0);
  628.                 if (bp == NULL)
  629.                     return(errorm);
  630.         
  631.                 /* if the buffer is displayed, get the window
  632.                    vars instead of the buffer vars */
  633.                 if (bp->b_nwnd > 0) {
  634.                     curbp->b_dotp = curwp->w_dotp;
  635.                     curbp->b_doto = curwp->w_doto;
  636.                 }
  637.  
  638.                 /* make sure we are not at the end */
  639.                 if (bp->b_linep == bp->b_dotp)
  640.                     return(errorm);
  641.         
  642.                 /* grab the line as an argument */
  643.                 blen = bp->b_dotp->l_used - bp->b_doto;
  644.                 if (blen > NSTRING)
  645.                     blen = NSTRING;
  646.                 strncpy(buf, bp->b_dotp->l_text + bp->b_doto,
  647.                     blen);
  648.                 buf[blen] = 0;
  649.         
  650.                 /* and step the buffer's line ptr ahead a line */
  651.                 bp->b_dotp = bp->b_dotp->l_fp;
  652.                 bp->b_doto = 0;
  653.  
  654.                 /* if displayed buffer, reset window ptr vars*/
  655.                 if (bp->b_nwnd > 0) {
  656.                     curwp->w_dotp = curbp->b_dotp;
  657.                     curwp->w_doto = 0;
  658.                     curwp->w_flag |= WFMOVE;
  659.                 }
  660.  
  661.                 /* and return the spoils */
  662.                 return(buf);        
  663.  
  664.         case TKVAR:    return(gtusr(token+1));
  665.         case TKENV:    return(gtenv(token+1));
  666.         case TKFUN:    return(gtfun(token+1));
  667.         case TKDIR:    return(errorm);
  668.         case TKLBL:    return(itoa(gtlbl(token)));
  669.         case TKLIT:    return(token);
  670.         case TKSTR:    return(token+1);
  671.         case TKCMD:    return(token);
  672.     }
  673. }
  674.  
  675. gtlbl(token)    /* find the line number of the given label */
  676.  
  677. char *token;    /* label name to find */
  678.  
  679. {
  680.     return(1);
  681. }
  682.  
  683. int stol(val)    /* convert a string to a numeric logical */
  684.  
  685. char *val;    /* value to check for stol */
  686.  
  687. {
  688.     /* check for logical values */
  689.     if (val[0] == 'F')
  690.         return(FALSE);
  691.     if (val[0] == 'T')
  692.         return(TRUE);
  693.  
  694.     /* check for numeric truth (!= 0) */
  695.     return((atoi(val) != 0));
  696. }
  697.  
  698. char *ltos(val)        /* numeric logical to string logical */
  699.  
  700. int val;    /* value to translate */
  701.  
  702. {
  703.     if (val)
  704.         return(truem);
  705.     else
  706.         return(falsem);
  707. }
  708.  
  709. char *mkupper(str)    /* make a string upper case */
  710.  
  711. char *str;        /* string to upper case */
  712.  
  713. {
  714.     char *sp;
  715.  
  716.     sp = str;
  717.     while (*sp) {
  718.         if ('a' <= *sp && *sp <= 'z')
  719.             *sp += 'A' - 'a';
  720.         ++sp;
  721.     }
  722.     return(str);
  723. }
  724.  
  725. char *mklower(str)    /* make a string lower case */
  726.  
  727. char *str;        /* string to lower case */
  728.  
  729. {
  730.     char *sp;
  731.  
  732.     sp = str;
  733.     while (*sp) {
  734.         if ('A' <= *sp && *sp <= 'Z')
  735.             *sp += 'a' - 'A';
  736.         ++sp;
  737.     }
  738.     return(str);
  739. }
  740.  
  741. int abs(x)    /* take the absolute value of an integer */
  742.  
  743. int x;
  744.  
  745. {
  746.     return(x < 0 ? -x : x);
  747. }
  748.  
  749. int ernd()    /* returns a random integer */
  750.  
  751. {
  752.     seed = abs(seed * 1721 + 10007);
  753.     return(seed);
  754. }
  755.  
  756. int sindex(source, pattern)    /* find pattern within source */
  757.  
  758. char *source;    /* source string to search */
  759. char *pattern;    /* string to look for */
  760.  
  761. {
  762.     char *sp;    /* ptr to current position to scan */
  763.     char *csp;    /* ptr to source string during comparison */
  764.     char *cp;    /* ptr to place to check for equality */
  765.  
  766.     /* scanning through the source string */
  767.     sp = source;
  768.     while (*sp) {
  769.         /* scan through the pattern */
  770.         cp = pattern;
  771.         csp = sp;
  772.         while (*cp) {
  773.             if (!eq(*cp, *csp))
  774.                 break;
  775.             ++cp;
  776.             ++csp;
  777.         }
  778.  
  779.         /* was it a match? */
  780.         if (*cp == 0)
  781.             return((int)(sp - source) + 1);
  782.         ++sp;
  783.     }
  784.  
  785.     /* no match at all.. */
  786.     return(0);
  787. }
  788.